package com.jushu.storbox.view.pulltorefresh;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

import com.jushu.storbox.R;
import com.jushu.storbox.adapter.MyFileListAdapter.ViewHolder;
import com.jushu.storbox.entities.FileFolderInfo;
import com.jushu.storbox.util.PublicTools;

public class MyScrollView extends ScrollView implements ImyScrollView {

	private boolean isDraging = false;

	/** baseAdaptor */
	private BaseAdapter bassAdapter;

	/** LinearLayout */
	private LinearLayout layout ;

	/** Context */
	private Context context;

	/** one page item size */
	private static int PAGE_SIZE = 20;

	/** page */
	private int page = 0;

	private int last_scroll_Y = 0;

	private int last_Y = 0;

	private boolean isButtom = false;

	private static int lastScrollY = -1;

	private int scrollViewHeight;

	private static View scrollLayout;

	private boolean loadOnce;

	/** item height */
	public int itemHeight = 0;

	/** whether ScrollView is scrolling */
	private boolean stopScroll = false;

	/** The view will be refreshed */
	private View freshView;

	/** obtain refresh view */
	public View getFreshView() {
		return freshView;
	}

	/** obtain refresh view by index */
	public View getFreshView(int index) {
		return itemViewMap.get(index);
	}

	/** set refresh view */
	public void setFreshView(View freshView) {
		this.freshView = freshView;
	}

	// private List<View> viewList = new ArrayList<View>();

	/** view list */
	private List<View> itemViewMap = new ArrayList<View>();

	public MyScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		this.context = context;
	}

	@Override
	public void setAdptor(BaseAdapter mAdapter) {
		this.bassAdapter = mAdapter;
	}
	
	public BaseAdapter getAdptor() {
		// TODO Auto-generated method stub
		return this.bassAdapter;
	}

	@Override
	public void setLayout(LinearLayout layout) {
		this.layout = layout;
	}
//	@Override
//	public boolean onInterceptHoverEvent(MotionEvent event) {
//		// TODO Auto-generated method stub
//		int action = event.getAction();
//		boolean touchFlag = false;
//		switch (action) {
//		case MotionEvent.ACTION_DOWN:
//			break;
//		case MotionEvent.ACTION_UP:
//			break;
//		case MotionEvent.ACTION_CANCEL:
//			break;
//		case MotionEvent.ACTION_MOVE:
//			touchFlag = true;
//			break;
//		}
//		return (touchFlag && super.onInterceptHoverEvent(event));
//	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		isDraging = false;
		int action = ev.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			break;
		case MotionEvent.ACTION_UP:
			if (!stopScroll) {
				Message msg = new Message();
				msg.what = 1;
				msg.obj = this;
				handler.sendMessage(msg);
			}
			// last_Y = last_scroll_Y;
			int layout_y = 0;
			if (null != layout) {
				layout_y = layout.getScrollY();
			}
			if (isDraging || 0 != layout_y) {
				releaseToRefresh();
			}
			last_Y = 0;
			isButtom = false;
			break;
		case MotionEvent.ACTION_CANCEL:
			return false;
		case MotionEvent.ACTION_MOVE:
			scrollLayout = layout;
			scrollViewHeight = getHeight();
			if (scrollViewHeight > scrollLayout.getHeight()) {
				return false;
			}
			if (scrollViewHeight + this.getScrollY() >= scrollLayout
					.getHeight() && 0 != scrollLayout.getHeight()) {
				if (isButtom) {

				} else {
					last_Y = (int) ev.getY();
				}
				isButtom = true;
				last_scroll_Y = (int) (last_Y - ev.getY());
				pullToRefresh(last_scroll_Y);
			} else {
				if (isDraging) {
					last_scroll_Y = (int) (last_Y - ev.getY());
					pullToRefresh(last_scroll_Y);
				}
			}

			break;
		}
		return super.onTouchEvent(ev);
	}

	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			MyScrollView myScrollView = null;
			switch (msg.what) {
			case 0:
				final View item = (View) msg.obj;
				new Thread(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub
						Message addMsg = new Message();
						addMsg.what = 10;
						addMsg.obj = item;
						handler.sendMessage(addMsg);
					}
				}).start();

				break;
			case 10:
				View itemView = (View) msg.obj;
				getColumn(null, itemHeight, layout).addView(itemView);
				itemViewMap.add(itemView);
				setFreshView(itemView);
				break;
			case 1:

				myScrollView = (MyScrollView) msg.obj;
				int scrollY = myScrollView.getScrollY();
				if (scrollY == lastScrollY) {
					if (null != scrollLayout && scrollViewHeight + scrollY + itemHeight >= scrollLayout
							.getHeight() && 0 != scrollLayout.getHeight()) {
						loadDatas();
					}
					// myScrollView.checkVisibility(viewList);
					// myScrollView.checkVisibility();
				} else {
					lastScrollY = scrollY;
					Message message = new Message();
					message.obj = myScrollView;
					message.what = 1;
					handler.sendMessageDelayed(message, 5);
				}
				break;
			case 2:
				break;
			default:
				break;
			}
		};
	};

	private void loadDatas() {
		stopScroll = true;
		BaseAdapter mAdaptor = bassAdapter;
		if (null != mAdaptor) {
			int startIndex = page * PAGE_SIZE;
			int endIndex = page * PAGE_SIZE + PAGE_SIZE;
			if (startIndex < mAdaptor.getCount()) {
				if (0 != page) {
					Toast.makeText(
							getContext(),
							context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label),
							Toast.LENGTH_SHORT).show();
				}
				if (endIndex > mAdaptor.getCount()) {
					endIndex = mAdaptor.getCount();
				}
				for (int i = startIndex; i < endIndex; i++) {

					View currentView = mAdaptor.getView(i, null, null);
					if (null != currentView) {
						Message msg = new Message();
						msg.what = 0;
						msg.obj = currentView;
						handler.sendMessage(msg);
					}
				}
				if (0 != page) {
					new Handler().postDelayed(new Runnable() {
						public void run() {
							scrollToNextItem(itemHeight);
						}
					}, 1000);
				}

				page++;
			} else {
			}
		}

		stopScroll = false;
	}

	private LinearLayout getColumn(View item, int itemHeigth,
			LinearLayout column) {
		return column;
	}

	@Override
	public void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		// @SuppressWarnings("static-access")

		// LayoutInflater miInflater = (LayoutInflater) context
		// .getSystemService(context.LAYOUT_INFLATER_SERVICE);
		// View item = miInflater.inflate(R.layout.item, null);
		// itemHeight = item.getHeight();
		// Log.d("ontouch~", "itemHeight:"+itemHeight);
		// android.view.ViewGroup.LayoutParams params = item.getLayoutParams();
		if (!loadOnce) {
			// if(0 == PublicTools.getScrollViewHeight(context)){
			scrollViewHeight = getHeight();
			// PublicTools.setScrollViewHeight(context, scrollViewHeight);
			// }else{
			// scrollViewHeight = PublicTools.getScrollViewHeight(context);
			// }

			View item = null;

			// if(0 == PublicTools.getItemHeight(context)){
			item = PublicTools.getMeasureItem(context, R.layout.item_filelist,
					R.id.item_img_re, item);
			itemHeight = item.getMeasuredHeight();
			// PublicTools.setItemHeight(context, i_Height);
			// }else{
			// i_Height = PublicTools.getItemHeight(context);
			// }
			PAGE_SIZE = getPageCount(scrollViewHeight, itemHeight) + 5;
			loadOnce = true;
		}
	}

	@Override
	public void notifyAllItem() {
		// TODO Auto-generated method stub
		itemViewMap = new ArrayList<View>();
		loadDatas();
	}

	public void resetList() {
		itemViewMap = new ArrayList<View>();
		bassAdapter = null;
	}
	
	public List<View> getItemViewList(){
		return itemViewMap;
	}

	@Override
	public void notifyAt(int index) {
		// TODO Auto-generated method stub
	}

	@Override
	public void removeItemAt(int index) {
		// TODO Auto-generated method stub
		try {
			layout.removeViewAt(index);
			itemViewMap.remove(index);

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

	@Override
	public void removeAllItem() {
		// TODO Auto-generated method stub
		try {
			bassAdapter = null;
			layout.removeAllViews();
			page = 0;
			itemViewMap = new ArrayList<View>();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

	@Override
	public void addOneItem(View item) {
		// TODO Auto-generated method stub
		layout.addView(item);
		itemViewMap.add(item);
		Log.d("addOneItem", "PAGE_SIZE | bassAdapter.getCount()[addOneItem]:"+PAGE_SIZE + "|" + bassAdapter.getCount());
		if (PAGE_SIZE > bassAdapter.getCount()) {
			page++;
		}
		Log.d("addOneItem", "page[addOneItem]:"+page);
	}

	@Override
	public void addOneItemAt(int index, View item) {
		// TODO Auto-generated method stub
		layout.addView(item, index);
		itemViewMap.add(index, item);
		Log.d("addOneItem", "PAGE_SIZE | bassAdapter.getCount()[addOneItemAt]:"+PAGE_SIZE + "|" + bassAdapter.getCount());
		if (PAGE_SIZE > bassAdapter.getCount()) {
			page++;
		} 
		Log.d("addOneItem", "page[addOneItemAt]:"+page);
	}

	private void pullToRefresh(int scroll_Y) {
		this.setVerticalScrollBarEnabled(false);
		layout.scrollTo(0, scroll_Y / 3);
		isDraging = true;
	}

	private void releaseToRefresh() {
		this.setVerticalScrollBarEnabled(true);
		layout.scrollTo(0, 0);
		last_Y = 0;
		isDraging = false;
	}

	private void scrollToNextItem(int itemHeight) {
		this.scrollTo(0, this.getScrollY() + itemHeight);
	}

	// private void isLoading() {
	// LayoutInflater miInflater = (LayoutInflater) context
	// .getSystemService(context.LAYOUT_INFLATER_SERVICE);
	// wait_item = miInflater.inflate(R.layout.item_wait, null);
	// getColumn(null, itemHeight, layout).addView(wait_item);
	// }
	//
	// private void loadingComplete() {
	// layout.scrollTo(0, 0);
	// last_Y = 0;
	// getColumn(null, itemHeight, layout).removeView(wait_item);
	// }

	@Override
	public void removeItem(View item) {
		// TODO Auto-generated method stub
		try {
			layout.removeView(item);
			itemViewMap.remove(item);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	@Override
	public void notifyitem(View item, Object entity) {
        ViewHolder holder = (ViewHolder) item.getTag();
        FileFolderInfo info = (FileFolderInfo) entity;
        holder.fileName.setText(info.getName());
        holder.date.setText(PublicTools.longToString(info.getModifiedAt()));
        holder.fileInformation = info;
	}

	private int getPageCount(int baseHeight, int itemHeight) {
		int count = 20;
		double d_count = (double) baseHeight / itemHeight;
		count = (int) Math.ceil(d_count);
		return count;
	}
}
